﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>

//void* malloc (size_t size);
//int main()
//{
//	int* p = (int*)malloc(20);
//	if (p == NULL)
//	{
//		perror("malloc");
//		return 1;
//	}
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		*(p + i) = i + 1;
//	}
//	free(p);//把空间的使用权还给操作系统
//	//传递给free函数的是要释放的内存空间的起始地址
//	p = NULL;
//	return 0;
//}


//向内存申请5个整型的空间
//int main()
//{
//	/*int* p = (int*)malloc(5 * sizeof(int));
//	if (p == NULL)
//	{
//		perror("malloc");
//		return 1;
//	}*/
//	int* p = (int*)calloc(5, sizeof(int));
//	if (p == NULL)
//	{
//		perror("malloc");
//		return 1;
//	}
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		printf("%d ", *(p + i));
//	}
//	free(p);
//	p = NULL;
//	return 0;
//}

//int main()
//{
//	int* p = (int*)malloc(5 * sizeof(int));
//	if (p == NULL)
//	{
//		perror("malloc");
//		return 1;
//	}
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		*(p + i) = i + 1;
//	}
//	//希望将空间调整为40个字节
//	int* ptr = (int*)realloc(p, 40);
//	if (ptr != NULL)
//	{
//		p = ptr;
//		for (int j = 5; j < 10; i++)
//		{
//			*(p + i) = i + 1;
//
//		}
//		for (int j = 5; j < 10; i++)
//		{
//			printf("%d ", *(p + i));
//		}
//		free(p);
//		p = NULL;
//	}
//	else
//	{
//		perror("realloc");
//		free(p);
//		p = NULL;
//
//	}
//	//使用40个空间了
//
//
//	return 0;
//}


//realloc可以完成malloc一样的功能

//int main()
//{
//	realloc(NULL, 20);//===malloc(20)
//	return 0;
//}

//int main()
//{
//	int* p = (int*)malloc(INT_MAX);
//	if (p == NULL)
//		perror("malloc");
//	return 0;
//}


//对空指针的解引用操作
#include <assert.h>
//int main()
//{
//	int* p = (int*)malloc(20);
//	/*if (p == NULL)
//	{
//		perror("malloc");
//		return 1;
//	}*/
//	assert(p);
//	*p = 20;
//	return 0;
//}

//void test()
//{
//	int i = 0;
//	int* p = (int*)malloc(10 * sizeof(int));
//	if (NULL == p)
//	{
//		exit(EXIT_FAILURE);
//	}
//	for (i = 0; i <= 10; i++)
//	{
//		*(p + i) = i;//当i是10的时候越界访问
//	}
//	free(p);
//}
//
//int main()
//{
//	test();
//	return 0;
//}


//int main()
//{
//	int a = 2;
//	int* p = &a;
//	free(p);
//	p = NULL;
//	return 0;
//}


//使⽤free释放⼀块动态开辟内存的⼀部分
//int main()
//{
//	int* p = (int*)malloc(100);
//	if (p == NULL)
//	{
//		return 1;
//	}
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		*p = i + 1;
//		p++;
//	}
//	free(p);//这里的p不再是动态申请的内存的起始位置
//	p = NULL;
//	return 0;
//}

//对同⼀块动态内存多次释放
//void test()
//{
//	int* p = (int*)malloc(100);
//	free(p);
//	p = NULL;
//	free(p);//重复释放
//}
//
//int main()
//{
//	test();
//	return 0;
//}

//动态开辟内存忘记释放（内存泄漏）
//1、谁申请谁释放 2、如果不能释放，告诉使用的人，记得释放
//malloc/free成对释放
//void test()
//{
//	int* p = (int*)malloc(100);
//	if (NULL != p)
//	{
//		*p = 20;
//	}
//}
//
//int main()
//{
//	test();
//	//
//	while (1);
//}

//void test()
//{
//	int* p = (int*)malloc(100);
//	int n = 3;
//	if (n > 0)
//		return;
//	free(p);
//	p = NULL;
//}
//
//int main()
//{
//	test();
//	//
//	while (1);
//}
#include <string.h>
//char* GetMemory()
//{
//	char* p = (char*)malloc(100);
//	return p;
//}
//void Test(void)
//{
//	char* str = NULL;
//	str=GetMemory();
//	strcpy(str, "hello world");
//	printf(str);
//	free(str);
//	str = NULL;
//}
//int main()
//{
//	Test();
//	return 0;
//}
//内存泄漏
//程序崩溃


//char* GetMemory(void)
//{
//	char p[] = "hello world";
//	return p;
//}
//void Test(void)
//{
//	char* str = NULL;
//	str=GetMemory();
//	//等getMemory函数返回后，使用str指针去访问p数组，就是非法访问，因为p数组的内存还给了操作系统
//	//str是野指针
//	printf(str);
//	
//}
//int main()
//{
//	Test();
//	return 0;
//}

//int* test()
//{
//	int n = 10;
//	return &n;
//}
//
//int main()
//{
//	int*p=test();
//	printf("hehe\n");
//	printf("%d\n", *p);
//	return 0;
//}

//void GetMemory(char** p, int num)
//{
//	*p = (char*)malloc(num);
//}
//void Test(void)
//{
//	char* str = NULL;
//	GetMemory(&str, 100);
//	strcpy(str, "hello");
//	printf(str);
//	free(str);
//	str = NULL;
//}
//
//int main()
//{
//	Test();
//	return 0;
//}

//void Test(void)
//{
//	char* str = (char*)malloc(100);
//	strcpy(str, "hello");
//	free(str);
//	if (str != NULL)
//	{
//		strcpy(str, "world");
//		printf(str);
//	}
//}
//
//int main()
//{
//	Test();
//	return 0;
//}

//柔性数组
//结构体中，最后一个成员
//最后一个成员是数组，数组没有指定大小
//这个数组才是柔性数组

//struct S
//{
//	char c;
//	int n;
//	int arr[];//柔性数组
//};

//struct S
//{
//	char c;
//	int n;
//	int arr[0];//柔性数组
//};


//sizeof 返回的这种结构⼤⼩不包括柔性数组的内存
//struct S
//{
//	int n;//4
//	int arr[];
//};
//
//int main()
//{
//	//printf("%zd\n", sizeof(struct S));
//	struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));
//	if (ps = NULL)
//	{
//		perror("malloc");
//		return 1;
//	}
//	ps->n = 100;
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		ps->arr[i] = i;
//	}
//	//调整空间
//	struct S* ptr=(struct S*)realloc(ps, sizeof(struct S) + 10 * sizeof(int));
//	if (ptr != NULL)
//	{
//		ps = ptr;
//	}
//	//...
//	free(ps);
//	ps = NULL;
//	return 0;
//}

//struct S
//{
//	int n;
//	int* arr;
//};
//int main()
//{
//	struct S* ps = (struct S*)malloc(sizeof(struct S));
//	if (ps == NULL)
//	{
//		perror("malloc");
//		return 1;
//	}
//	ps->arr = (int*)malloc(5 * sizeof(int));
//	if (ps->arr == NULL)
//	{
//		perror("malloc");
//		return 1;
//	}
//	ps->n = 100;
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		ps->arr[i] = i;
//	}
//
//	//调整数组
//	int* ptr = (int*)realloc(ps->arr, 10 * sizeof(int));
//	if (ptr != NULL)
//	{
//		ps->arr = ptr;
//	}
//	//使用
//
//	//释放
//	free(ps->arr);
//	free(ps);
//	return 0;
//}

